home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mission 3
/
Mission 3.zip
/
Mission 3.iso
/
zugabe
/
va45
/
visual45
/
library
/
wrkspace
/
workspa.s
< prev
Wrap
Text File
|
1998-08-14
|
13KB
|
446 lines
IFD GWVA_WSP_CTE_WORKSPACE
IFND GWVA_WSP_CTE_TYPICAL_NB_BLOC
GWVA_WSP_CTE_TYPICAL_NB_BLOC=0
ENDC
GWVA_WPS_COPY_AUTOSIZE=0
text
rsreset
GWVA_WSP_WORKSPACE_NEXT: rs.l 1 ;!!!!! cf. _GWVA_VAR_WORKSPACE_FIRST
GWVA_WSP_WORKSPACE_SIZE: rs.l 1 ; en octets ! total, header compris
GWVA_WSP_WORKSPACE_BLOCS: rs.l 0
_GWVA_WSP_WORKSPACE_STRUCT_LENGTH: rs.l 0
rsreset
GWVA_WSP_FREEBLOC_NEXT: rs.l 1 ;!!!!! cf. _GWVA_VAR_BLOC_FIRST_FREE
GWVA_WSP_FREEBLOC_SIZE: rs.l 1 ; en nombre de longs effectivement allouables (disponibles) a un usedbloc.
GWVA_WSP_FREEBLOC_BEGIN: rs.l 0
_GWVA_WSP_FREEBLOC_STRUCT_LENGTH: rs.l 0
rsreset
GWVA_WSP_USEDBLOC_SIZE: rs.l 1 ; en nombre de longs disponibles dans le bloc, hors header
GWVA_WSP_USEDBLOC_BEGIN: rs.l 0
_GWVA_WSP_USEDBLOC_STRUCT_LENGTH: rs.l 0
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_MORE_WORKSPACE
;* Description : Mallocs an area to add to the workspace
;*
;* in : GWVA_WSP_CTE_WORKSPACE : size of workspace :
;* if GWVA_WSP_CTE_TYPICAL_NB_BLOC=0 or not defined
;* then =total size of workspace (in byte)
;* else =typical (max) size of one bloc
;* in : GWVA_WSP_CTE_TYPICAL_NB_BLOC : number of blocs to be used in this workspace (optionnal)
;* NB: does not need to be the exact number of blocs ; it's a hint given
;* to the algorithme so that it reserves memory for blocs informations.
;* If less blocs are effectivly used, there will be more memory usable for blocs ;
;* if more blocs are effectivly used, there will be less memory usable for blocs ;
;* if the exact number of bloc is used, the amount of memory needed is garanteed.
;* 0 is a special value (cf. GWVA_WSP_CTE_WORKSPACE).
;*
;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_MORE_WORKSPACE:
move.l #GWVA_WSP_CTE_WORKSPACE,d0
move.l #GWVA_WSP_CTE_TYPICAL_NB_BLOC,d1
tst.l d0
beq.s .fin_erreur
tst.l d1
beq.s .deja_calc
add.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH,d0
mulu.l d1,d0
.deja_calc:
move.l d0,-(sp)
add.l #_GWVA_WSP_WORKSPACE_STRUCT_LENGTH,d0
MXALLOC d0
IFNE DEBUG
move.l a6,d0
ENDC
tst.l d0
beq.s .malloc_erreur
addq.l #3,d0
andi.l #~3,d0
move.l d0,a0
move.l (sp)+,d0
; on doit chercher l'endroit ou inserer ce workspace (a0) dans la file
; ie: le bloc actuel (a1) est avant le nouveau et le suivant est apres
lea _GWVA_VAR_WORKSPACE_FIRST,a2
.pas_encore:
movea.l a2,a1
move.l GWVA_WSP_WORKSPACE_NEXT(a1),a2 ; next=last first
tst.l a2
beq.s .fin_de_liste ; deja fini ?
cmpa.l a0,a2
bmi.s .pas_encore
.trouve:
.fin_de_liste:
move.l GWVA_WSP_WORKSPACE_NEXT(a1),GWVA_WSP_WORKSPACE_NEXT(a0)
move.l a0,GWVA_WSP_WORKSPACE_NEXT(a1)
move.l d0,GWVA_WSP_WORKSPACE_SIZE(a0)
.build_workspace:
lea GWVA_WSP_WORKSPACE_BLOCS(a0),a0
; informe ce workspace avec un faux usedbloc dont la taille est correcte
sub.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH,d0
lsr.l #2,d0 ; en nombre de longs
move.l d0,GWVA_WSP_USEDBLOC_SIZE(a0) ; size = d0
; libere ce faux usedbloc
lea GWVA_WSP_USEDBLOC_BEGIN(a0),a0
bsr GWVA_WSP_FREE_BLOC
.fin_ok:
clr.w d7
rts
.malloc_erreur:
move.l (sp)+,d0
.fin_erreur:
; retourne une erreur
move.w #GWVA_ERROR_GENERIC,d7
rts
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_NEW_BLOC
;* Description : Gets one bloc of specified size (size is rounded up to long)
;*
;* in : d0.l = size of the bloc in bytes
;*
;* out : a0.l-> bloc
;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_NEW_BLOC:
tst.l d0
beq.s .fin_erreur
moveq.l #3,d1
and.l d0,d1
sne.b d1
neg.b d1
lsr.l #2,d0 ; en nbre de longs
add.l d1,d0
lea _GWVA_VAR_FREEBLOC_FIRST,a0
.get_next_free_bloc:
move.l GWVA_WSP_FREEBLOC_NEXT(a0),d1
beq.s .fin_erreur
movea.l a0,a1 ; garde le précédent pour faire lien
movea.l d1,a0
cmp.l GWVA_WSP_FREEBLOC_SIZE(a0),d0
beq.s .get_the_free_bloc
bgt.s .get_next_free_bloc
; ici (a0) on donc un bloc de bonne taille et on va couper dedans
lea _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d0.l*4),a2 ; nouveau debut du bloc libre
move.l GWVA_WSP_FREEBLOC_NEXT(a0),GWVA_WSP_FREEBLOC_NEXT(a2)
move.l GWVA_WSP_FREEBLOC_SIZE(a0),d1
sub.l d0,d1
sub.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1 ; dans l'usedbloc
beq.s .get_the_free_bloc_all
move.l d1,GWVA_WSP_FREEBLOC_SIZE(a2)
move.l a2,GWVA_WSP_FREEBLOC_NEXT(a1)
move.l d0,(a0)+ ; !!!!! GWVA_WSP_USEDBLOC_BEGIN
.fin_ok:
clr.w d7
rts
.fin_erreur:
move.w #GWVA_ERROC_GENERIC,d7
rts
.get_the_free_bloc_all:
move.l GWVA_WSP_FREEBLOC_SIZE(a0),d0
.get_the_free_bloc:
move.l GWVA_WSP_FREEBLOC_NEXT(a0),GWVA_WSP_FREEBLOC_NEXT(a1)
move.l GWVA_WSP_FREEBLOC_SIZE(a0),GWVA_WSP_USEDBLOC_SIZE(a0)
move.l d0,(a0)+ ; !!!!! GWVA_WSP_USEDBLOC_BEGIN
bra.s .fin_ok
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_FREE_BLOC
;* Description : Frees the pointed bloc
;*
;* in : a0.l-> bloc
;*
;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_FREE_BLOC:
move.l #_GWVA_VAR_FREEBLOC_FIRST,d1
lea -GWVA_WSP_USEDBLOC_BEGIN(a0),a0 ; pointe sur la structure
.get_next_free_bloc:
movea.l d1,a1
move.l GWVA_WSP_FREEBLOC_NEXT(a1),d1
beq.s .yen_a_pas ; dans le cas ou il n'y en a aucun
cmp.l a0,d1
blt.s .get_next_free_bloc
; ici a1 pointe un freebloc qui est avant
; et le freebloc suivant est apres
sub.l a1,d1 ; distance entre les deux freeblocs
sub.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH*2,d1 ; 1 dans le freebloc et 1 dans l'usedbloc
lsr.l #2,d1
sub.l GWVA_WSP_FREEBLOC_SIZE(a1),d1
cmp.l GWVA_WSP_USEDBLOC_SIZE(a0),d1
beq.s .juste_entre
; teste si l'usedbloc est collé juste apres le freebloc actuel
move.l GWVA_WSP_FREEBLOC_SIZE(a1),d1
lea GWVA_WSP_USEDBLOC_BEGIN(a1,d1.l*4),a2
cmp.l a2,a0
bne .ca_colle_pas_apres
move.l GWVA_WSP_USEDBLOC_SIZE(a0),d1
add.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1
add.l d1,GWVA_WSP_FREEBLOC_SIZE(a1)
.fin_ok:
clr.w d7
rts
.ca_colle_pas_apres:
; teste si l'usedbloc est collé juste avant le freebloc suivant
move.l GWVA_WSP_USEDBLOC_SIZE(a0),d1
lea _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d1.l*4),a2
move.l GWVA_WSP_FREEBLOC_NEXT(a1),d1
cmp.l a2,d1
bne.s .ca_colle_pas_avant_non_plus
move.l GWVA_WSP_FREEBLOC_NEXT(a1),a2
move.l a0,GWVA_WSP_FREEBLOC_NEXT(a1)
move.l GWVA_WSP_USEDBLOC_SIZE(a0),d1
add.l GWVA_WSP_FREEBLOC_SIZE(a2),d1
add.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1
move.l d1,GWVA_WSP_FREEBLOC_SIZE(a0)
move.l GWVA_WSP_FREEBLOC_NEXT(a2),GWVA_WSP_FREEBLOC_NEXT(a0)
bra.s .fin_ok
.yen_a_pas:
.ca_colle_pas_avant_non_plus:
; donc le bloc a liberer est isole entre deux usedblocs
move.l GWVA_WSP_USEDBLOC_SIZE(a0),GWVA_WSP_FREEBLOC_SIZE(a0)
move.l GWVA_WSP_FREEBLOC_NEXT(a1),GWVA_WSP_FREEBLOC_NEXT(a0)
move.l a0,GWVA_WSP_FREEBLOC_NEXT(a1)
bra.s .fin_ok
.juste_entre:
; cas particulier : l'usedbloc est juste collé entre deux freeblocs
move.l GWVA_WSP_FREEBLOC_NEXT(a1),a2
move.l GWVA_WSP_FREEBLOC_NEXT(a2),GWVA_WSP_FREEBLOC_NEXT(a1)
move.l GWVA_WSP_USEDBLOC_SIZE(a0),d1
add.l GWVA_WSP_FREEBLOC_SIZE(a1),d1
add.l GWVA_WSP_FREEBLOC_SIZE(a2),d1
add.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH*2/4,d1 ; 1 pour l'used bloc et 1 pour le freebloc suivant
move.l d1,GWVA_WSP_FREEBLOC_SIZE(a1)
bra.s .fin_ok
.fin_erreur:
move.w #GWVA_ERROC_GENERIC,d7
rts
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_SHRINK_BLOC
;* Description : Shrinks the pointed bloc so its size is reduced to the specified size
;*
;* Rq : content of the bloc remains unchanged
;*
;* in : a0.l-> bloc
;* in : d0.l = new size (<= old size) (bytes)
;*
;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_SHRINK_BLOC:
tst.l d0
beq.s .free
moveq.l #3,d1
and.l d0,d1
sne.b d1
neg.b d1
lsr.l #2,d0 ; en nbre de longs
add.l d1,d0
move.l GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d1
sub.l d0,d1
bmi.s .fin_erreur
sub.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d1 ; dans l'usedbloc
ble.s .pas_shrink_finalement
move.l d0,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
lea _GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0,d0.l*4),a0
move.l d1,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
.free:
bra GWVA_WSP_FREE_BLOC
.pas_shrink_finalement:
clr.w d7
rts
.fin_erreur:
move.w #GWVA_ERROC_GENERIC,d7
rts
;************************************************
;* Method name : -
;* Asm label :
;* Description : Shrinks the pointed bloc so it begins at specified address (size reduced)
;*
;* Rq : content of the bloc remains unchanged
;*
;* in : a0.l-> bloc
;* in : a1.l-> new begining of the bloc ( a0.l <= a1.l < a0.l+bloc size )
;*
;* out : a1.l-> new begining of the bloc rounded down to long !!! USE THIS ONE
;* out : d7.w = 0 ou GWVA_ERROC_GENERIC
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_SHRINKUP_BLOC:
move.l a1,d0
andi.w #~3,d0
move.l d0,a1
sub.l a0,d0 ; taille du freebloc
bmi.s .fin_erreur
lsr.l #2,d0
move.l GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d1
sub.l d0,d1
beq.s .free
bmi.s .fin_erreur
sub.l #_GWVA_WSP_USEDBLOC_STRUCT_LENGTH/4,d0 ; dans le freebloc
ble.s .pas_shrink_finalement
move.l d0,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0)
move.l d1,GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a1)
.free:
bra GWVA_WSP_FREE_BLOC
.pas_shrink_finalement:
clr.w d7
rts
.fin_erreur:
move.w #GWVA_ERROC_GENERIC,d7
rts
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_BLOC_MAX_SIZE_INQUIRE
;* Description : Inquires maximum bloc size
;*
;* out : d0.l = size in byte
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_BLOC_MAX_SIZE_INQUIRE:
lea _GWVA_VAR_FREEBLOC_FIRST,a0
clr.l d0 ; max=0 pour commencer
.suivant:
move.l GWVA_WSP_FREEBLOC_NEXT(a0),d1
beq.s .dernier
move.l d1,a0
move.l GWVA_WSP_FREEBLOC_SIZE(a0),d1
cmp.l d1,d0
bge.s .suivant ; pas mieux
move.l d1,d0
bra.s .suivant
.dernier:
lsl.l #2,d0 ; -> en octets
rts
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_BLOC_SIZE_INQUIRE
;* Description : Inquires the usedbloc size
;*
;* in : a0.l-> usedbloc
;*
;* out : d0.l = size
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_BLOC_SIZE_INQUIRE:
move.l GWVA_WSP_USEDBLOC_SIZE-GWVA_WSP_USEDBLOC_BEGIN(a0),d0
rts
;************************************************
;* Method name : -
;* Asm label : GWVA_WSP_BCOPY
;* Description : Copy datas
;*
;* Rq : saves d1-d7/a2-a7 ; a0-a1 are modified
;*
;* in : a0.l-> source
;* in : a1.l-> destination
;* in : d0.l = number of bytes (rounded up to long)
;* or d0.l = GWVA_WPS_COPY_AUTOSIZE : autosize (copy all the source taking care of destination size)
;*
;* out : d0.l = size effectively copied
;*
;* 07/98 : Création
;************************************************
GWVA_WSP_BCOPY:
move.l d1,-(sp)
tst.l d0
beq.s .autosize
moveq.l #3,d1
and.l d0,d1
sne.b d1
neg.b d1
lsr.l #2,d0 ; en nbre de longs
add.l d1,d0
move.l d0,d1
bra.s .size_ok
.autosize:
move.l GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a0),d0
move.l GWVA_WSP_USEDBLOC_SIZE-_GWVA_WSP_USEDBLOC_STRUCT_LENGTH(a1),d1
cmp.l d1,d0
bgt.s .size_inv
move.l d0,d1
.size_inv:
move.l d1,d0
.size_ok:
subq.l #1,d1
.bcl:
move.l (a0)+,(a1)+
dbra d1,.bcl
.fin_ok:
lsl.l #2,d0
move.l (sp)+,d1
rts
data
_GWVA_VAR_WORKSPACE_FIRST: dcb.b _GWVA_WSP_WORKSPACE_STRUCT_LENGTH
;!!!!! les routines s'attendent a trouver ici une structure
; de workspace pour chercher _NEXT seulement
_GWVA_VAR_FREEBLOC_FIRST: dcb.b _GWVA_WSP_FREEBLOC_STRUCT_LENGTH
;!!!!! les routines s'attendent a trouver ici une structure
; de bloc pour chercher _NEXT seulement
bss
ENDC